package com.xjh.basestudy.designmode.createMode.createMode1_Singleton;

/**
 * @Author XuJianHua
 * @Date 2022/9/12 0:11
 * @Description 单例模式-懒汉模式：当有调用者调用时才创建太阳
 */
public class LazySun {


    // 不再定义为一个常量，而是需要后续赋值的变量
    // volatile对静态变量的修饰则能保证变量值在各线程访问时的同步性、唯一性。
    // volatile修饰变量，对所有线程可见。A线程请求修改了值，回把值在内存中更新。B线程拿到的是内存中更新后的变量最新值！
    private volatile static LazySun lazySun;

    private LazySun() {//构造方法私有化

    }

    // 假设有两个线程（A、B）都想要创建实例
    public static LazySun getInstance() {//华山入口
    // 如果之前有实例、则不再创建实例
        if (lazySun == null) {//观日台入口
            // 同步代码块防止A、B线程同时进入代码（此时两个线程已经进入了第一个null的范围）
            synchronized (LazySun.class) {//观日者进行排队
                // 第二个null是当任意一个线程创建了实例，则已经进入第一个null的剩下的线程不再进行任何操作(比如A\B都进行了排队，当A/B任意一个创建了实例，剩下的一个线程则不再创建新实例)
                if (lazySun == null) {
                    lazySun = new LazySun();//只有排头兵造了太阳，旭日东升
                }
            }
        }
        return lazySun; //……阳光普照，其余人不必再造日
    }
}

/*我们一共用了2个嵌套的判空逻辑，这就是懒加载模式的“双检锁”：外层放宽入口，保证线程并发的高效性；内层加锁同步，保证实例化的单次运行。如此里应外合，不仅达到了单例模式的效果，还完美地保证了构建过程的运行效率，一举两得。*/